package websocket

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"sync"
	"time"

	"android-retrace/internal/session"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true // 允许跨域
	},
}

type Manager struct {
	clients    map[string]*Client
	register   chan *Client
	unregister chan *Client
	mutex      sync.RWMutex
}

type Client struct {
	ID         string
	Conn       *websocket.Conn
	Send       chan []byte
	Session    *session.Session
	Manager    *Manager
	lastActive int64 // 新增：最后心跳时间
}

type Message struct {
	Type string      `json:"type"`
	Data interface{} `json:"data"`
}

func NewManager() *Manager {
	return &Manager{
		clients:    make(map[string]*Client),
		register:   make(chan *Client),
		unregister: make(chan *Client),
	}
}

func (m *Manager) Run() {
	go m.heartbeatChecker() // 新增
	for {
		select {
		case client := <-m.register:
			m.mutex.Lock()
			m.clients[client.ID] = client
			m.mutex.Unlock()
			log.Printf("客户端 %s 已连接", client.ID)

		case client := <-m.unregister:
			m.mutex.Lock()
			if _, ok := m.clients[client.ID]; ok {
				delete(m.clients, client.ID)
				close(client.Send)
				// 清理会话和临时目录
				if client.Session != nil {
					client.Session.Cleanup()
				}
			}
			m.mutex.Unlock()
			log.Printf("客户端 %s 已断开", client.ID)
		}
	}
}

// 新增心跳检测
func (m *Manager) heartbeatChecker() {
	ticker := time.NewTicker(2 * time.Second)
	defer ticker.Stop()
	for range ticker.C {
		now := time.Now().Unix()
		m.mutex.RLock()
		for _, client := range m.clients {
			if now-client.lastActive > 300 {
				go func(c *Client) {
					m.unregister <- c
					c.Conn.Close()
				}(client)
			}
		}
		m.mutex.RUnlock()
	}
}

func (m *Manager) HandleWebSocket(c *gin.Context) {
	log.Println("WebSocket新的申请")
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Printf("WebSocket升级失败: %v", err)
		return
	}

	// 创建新会话
	sess := session.NewSession()
	client := &Client{
		ID:         sess.Token,
		Conn:       conn,
		Send:       make(chan []byte, 256),
		Session:    sess,
		Manager:    m,
		lastActive: time.Now().Unix(), // 新增
	}

	fmt.Println("新客户端连接，Token:", client.ID)

	log.Println("WebSocket升级成功")

	m.register <- client

	// 发送token给前端
	tokenMsg := Message{Type: "token", Data: client.ID}
	jsonData, _ := json.Marshal(tokenMsg)
	client.Conn.WriteMessage(websocket.TextMessage, jsonData)

	fmt.Println("新客户端连接，Token:", client.ID)

	log.Println("WebSocket升级成功")

	// 启动goroutine处理客户端
	go client.writePump()
	go client.readPump()
}

func (c *Client) readPump() {
	defer func() {
		c.Manager.unregister <- c
		c.Conn.Close()
	}()

	for {
		_, msg, err := c.Conn.ReadMessage()
		if err != nil {
			if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
				log.Printf("WebSocket错误: %v", err)
			}
			break
		}
		// 处理心跳
		var m Message
		if err := json.Unmarshal(msg, &m); err == nil && m.Type == "heartbeat" {
			c.lastActive = time.Now().Unix()
			continue
		}
	}
}

func (c *Client) writePump() {
	defer c.Conn.Close()

	for {
		select {
		case message, ok := <-c.Send:
			if !ok {
				c.Conn.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}

			if err := c.Conn.WriteMessage(websocket.TextMessage, message); err != nil {
				log.Printf("发送消息失败: %v", err)
				return
			}
		}
	}
}

func (m *Manager) SendToClient(clientID string, message Message) {
	m.mutex.RLock()
	client, exists := m.clients[clientID]
	m.mutex.RUnlock()

	if exists {
		// 将消息序列化为JSON
		jsonData, err := json.Marshal(message)
		if err != nil {
			log.Printf("序列化消息失败: %v", err)
			return
		}

		select {
		case client.Send <- jsonData:
		default:
			close(client.Send)
			m.mutex.Lock()
			delete(m.clients, clientID)
			m.mutex.Unlock()
		}
	}
}
